import axios from 'axios';
import qs from 'qs';
import fileDownload from 'js-file-download';

const baseUrl: string = '';

const getRequestUrl = (path: string, match: Record<string, any> | null) => {
  let requestPath: string = path.replace(/\/\//g, '/');
  if (!requestPath.includes('/:') || !match) {
    return `${baseUrl}${requestPath}`;
  }
  const list: string[] = path.split('/').map(item => {
    if (item.indexOf(':') === 0) {
      const value: string = match[item.slice(1)]
      if (value === null || value === undefined) {
        return item;
      }
      return '' + value;
    }
    return item;
  });
  requestPath = list.join('/');
  return `${baseUrl}${requestPath}`;
};

if (!localStorage.getItem('lastConfirmTime')) {
  localStorage.setItem('lastConfirmTime', '0');
}

axios.defaults.timeout = 1000 * 60 * 3;
axios.defaults.withCredentials = false;

axios.interceptors.request.use(request => {
  request.headers['X-ORIGINAL-URL'] = request.url;
  if (request.method === 'post') {
    if (request.data) {
      request.data = JSON.stringify(request.data);
    }
    request.headers['Content-Type'] = 'application/json;charset=UTF-8';
  }
  return request;
});

axios.interceptors.response.use(response => {
  let url: string = (response.config && response.config.url) ? response.config.url : '';
  if (url.includes('/api/export/')) {
      return response.data;
  }
  let responseData = response.data || {};
  let code: number = response.status;
  let data: any = responseData.data;
  let message: string = responseData.message || '';
  let success: boolean = Math.floor(code / 200) === 1 && code % 200 < 100;
  return { code, data, message, success };
},
error => {
  let response = error.response || {};
  let responseData = response.data || {};
  let code: number = response.status || 0;
  let data: any = null;
  let message: string = responseData.message || responseData.error || response.statusText || 'error';
  let success: boolean = false;
  let lastConfirmTime = Number(localStorage.getItem('lastConfirmTime'));
  if (code === 401 && new Date().getTime() - lastConfirmTime > 15000) {
    localStorage.setItem('lastConfirmTime', new Date().getTime() + '');
    if (window.confirm("用户未登录，要跳转登录页面吗？")) {
      window.location.reload();
    }
  }
  return Promise.reject({ code, data, message, success });
});

export const GET = async (path: string, match: Record<string, any> | null, data: any) => {
  const requestData = { params: data || {} };
  try {
    const res = await axios.get(getRequestUrl(path, match), requestData);
    return res;
  } catch (error) {
    return error;
  }
};

export const POST = async (path: string, match: Record<string, any> | null, data: any) => {
  const requestData = data || {};
  try {
    const res = await axios.post(getRequestUrl(path, match), requestData);
    return res;
  } catch (error) {
    return error;
  }
};

export const PATCH = async (path: string, match: Record<string, any> | null, data: any) => {
  const requestData = data || {};
  try {
    const res = await axios.patch(getRequestUrl(path, match), requestData);
    return res;
  } catch (error) {
    return error;
  }
};

export const DELETE = async (path: string, match: Record<string, any> | null, data: any) => {
  const requestData = { params: data || {} };
  try {
    const res = await axios.delete(getRequestUrl(path, match), requestData);
    return res;
  } catch (error) {
    return error;
  }
};

export const download = async (path: string, match: Record<string, any> | null, data: any, filename: string) => {
  let url = getRequestUrl(path, match);
  let params = '';
  if (data) {
    params = qs.stringify(data);
  }
  if (params) {
    url = url + '?' + params;
  }
  try {
    const res = await axios.get(url, { responseType: 'blob' });
    fileDownload(res as any, filename);
    return true;
  } catch (error) {
    return error;
  }
};

export const downloadData = async (path: string, match: Record<string, any> | null, data: any, filename: string) => {
  let url = getRequestUrl(path, match);
  try {
    const res = await axios.post(url, data, { responseType: 'blob' });
    fileDownload(res as any, filename);
    return true;
  } catch (error) {
    return error;
  }
};
